package leetcode.medium.generatematrix;

import util.annotation.Solved;

import java.util.Arrays;

/**
 * <a href="https://leetcode.cn/problems/spiral-matrix-ii/">59. 螺旋矩阵 II</a>
 */
@Solved
public class Solution {
    private final static int DOWN = 1;
    private final static int RIGHT = 1;
    private final static String X = "X";
    private final static String Y = "Y";

    public int[][] generateMatrix(int n) {
        int count = 1;
        int[][] res = new int[n][n];
        int i = 0, j = 0;
        int directionX = RIGHT, directionY = DOWN;
        String curCoordinate = X;
        while (count <= n * n) {
            res[i][j] = count;
            if (curCoordinate.equals(X)) {
                // 已经到头或下一个位置已经被填充
                if (isEnd(res, i, j, curCoordinate, directionX)) {
                    // 切换坐标轴为 Y
                    curCoordinate = Y;
                    // 切换 X 方向
                    directionX = -directionX;
                    i += directionY;
                } else {  // 否则继续前进
                    j += directionX;
                }
            } else {  // Y
                // 已经到头或下一个位置已经被填充
                if (isEnd(res, i, j, curCoordinate, directionY)) {
                    // 切换坐标轴为 X
                    curCoordinate = X;
                    // 切换 Y 方向
                    directionY = -directionY;
                    j += directionX;
                } else {  // 否则继续前进
                    i += directionY;
                }
            }
            count++;
        }
        return res;
    }

    /**
     * 判断当前是否已到达终点
     * @param matrix 方形矩阵
     * @param i 行坐标
     * @param j 列坐标
     * @param coordinate 坐标轴，横轴（X）或纵轴（Y）
     * @param direct 方向。含义取决于坐标轴：坐标轴为 Y，1代表向下，-1代表向上；坐标轴为 X，1代表向右，-1代表向左
     * @return 是否已到达终点
     */
    private boolean isEnd(int[][] matrix, int i, int j, String coordinate, int direct) {
        if (coordinate.equals(X)) {
            if (direct == RIGHT) {
                return j == matrix.length - 1 || matrix[i][j + direct] != 0;
            }
            return j == 0 || matrix[i][j + direct] != 0;
        } else {  // Y
            if (direct == DOWN) {
                return i == matrix.length - 1 || matrix[i + direct][j] != 0;
            }
            return i == 0 || matrix[i + direct][j] != 0;
        }
    }

    public static void main(String[] args) {
        System.out.println(Arrays.deepToString(new Solution().generateMatrix(11)));
    }
}
